package com.yungam.imcs.controller.auth;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yungam.common.bean.menu.Menu;
import com.yungam.common.bean.menu.RolePermission;
import com.yungam.common.bean.role.Role;
import com.yungam.common.bean.team.Team;
import com.yungam.common.bean.user.User;
import com.yungam.common.response.RetDTO;
import com.yungam.common.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@Api(tags = "Auth 接口")
@RestController
@RequestMapping("/auth")
public class AuthController {

    @Resource
    private UserService userService;
    @Resource
    private MenuService menuService;
    @Resource
    private TeamService teamService;
    @Resource
    private RolePermissionService permissionService;
    @Resource
    private RoleService roleService;

    @ApiOperation("登录功能")
    @GetMapping("/login")
    public RetDTO<?> login(@ApiParam("用户名") @RequestParam(value = "userName") String userName,
                           @ApiParam("密码") @RequestParam(value = "password") String password,
                           @ApiIgnore HttpServletResponse response) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        qw.eq("user_name", userName);
        User user = userService.getOne(qw);
        // 查询用的角色名称和班组名称, 个人信息页面需要
        if (user.getTeamId() != null) {
            Team team = teamService.getById(user.getTeamId());
            user.setTeamName(team.getTeamName());
        }
        if (user.getRoleId() != null) {
            Role role = roleService.getById(user.getRoleId());
            user.setRoleName(role.getRoleName());
        }
        // 加密密码进行比对
        String decode = null;
        if (StringUtils.isNotEmpty(password)) decode = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        if (!Objects.equals(decode, user.getPassword())) return RetDTO.error("用户名或密码不正确");
        // 验证成功
        String token = JWT.create().withAudience(userName)
                            .withExpiresAt(new Date(System.currentTimeMillis() + 12 * 60 * 60 * 1000))
                            .sign(Algorithm.HMAC256(user.getPassword()));
        response.setHeader("token", token);
        response.setHeader("Access-Control-Expose-Headers", "token");
        return RetDTO.data(user);
    }

    @ApiOperation("查询登录角色所拥有的菜单")
    @GetMapping("/menuList")
    public RetDTO<?> getMenuList(@ApiParam("角色 id") @RequestParam Integer roleId) {
        Map<Integer, List<Menu>> map = new HashMap<>();  // { k: parentId, v: Children }
        List<Menu> parentList = new ArrayList<>(); // 所有的父级菜单项
        // 根据『role_id』获取其拥有的『menu_id』List
        QueryWrapper<RolePermission> qw = new QueryWrapper<>();
        qw.eq("role_id", roleId);
        List<RolePermission> menuIdList = permissionService.list(qw);
        List<Integer> ids = menuIdList.stream().map(RolePermission::getMenuId).collect(Collectors.toList());
        // 根据 『idList』获取菜单项
        QueryWrapper<Menu> menuQw = new QueryWrapper<>();
        menuQw.in("id", ids);
        List<Menu> list = menuService.list(menuQw);
        for (Menu menu : list) {
            if (menu.getParentId() == 0) {
                parentList.add(menu);
            } else {
                List<Menu> children = map.getOrDefault(menu.getParentId(), new ArrayList<>());
                children.add(menu);
                map.put(menu.getParentId(), children);
            }
        }
        for (Menu fa : parentList) {
            if (map.containsKey(fa.getId())) {
                List<Menu> child = map.get(fa.getId());
                child.sort((x, y) -> (Integer) (x.getWeight() - y.getWeight())); // 按照权重排序
                fa.setSubItems(child);
            }
        }
        parentList.sort((x, y) -> (Integer) (x.getWeight() - y.getWeight())); // 按照权重排序
        return RetDTO.data(parentList);
    }

    @ApiOperation("修改个人信息")
    @PostMapping("/personal")
    public RetDTO<?> savePersonal(@ApiParam("用户实体") @RequestBody User user) {
        userService.updateById(user);
        User newUser = userService.getById(user.getId());
        return RetDTO.data(newUser);
    }

}
